1 module directx.d2d1helper;
2 /*=========================================================================*\
3 
4     Copyright (c) Microsoft Corporation.  All rights reserved.
5 
6     File: D2D1helper.h
7 
8     Module Name: D2D
9 
10     Description: Helper files over the D2D interfaces and APIs.
11 
12 \*=========================================================================*/
13 
14 version(Windows):
15 
16 version(Direct2D_1_3)
17     version = Direct2D_1_2;
18 version(Direct2D_1_2)
19     version = Direct2D_1_1;
20 version(Direct2D_1_1):
21     version = Direct2D_1_0;
22 
23 version(DirectWrite):
24 version(WinCodec):
25 version(Direct2D_1_0):
26 
27 public import directx.d2d1;
28 
29 struct D2D1
30 {
31     //
32     // The default trait type for objects in D2D is float.
33     //
34 	template TypeTraits(T)
35 	{
36 		alias Point = D2D1_POINT_2F;
37 		alias Size = D2D1_SIZE_F;
38 		alias Rect = D2D1_RECT_F;
39 	}
40 	
41 	template TypeTraits(T : UINT32)
42 	{
43 		alias Point = D2D1_POINT_2U;
44 		alias Size = D2D1_SIZE_U;
45 		alias Rect = D2D1_RECT_U;
46 	}
47 
48     static nothrow
49     FLOAT FloatMax()
50     {
51         static if ( __traits(compiles, FLT_MAX.stringof) )
52             return FLT_MAX;
53         else
54             return 3.402823466e+38F;
55     }
56 
57     //
58     // Construction helpers
59     //
60 
61     template Point2(Type)
62 	{
63     	struct Point2_(Type)
64 		{
65 			Type x;
66 			Type y;
67 		}
68     	
69 		static Point2_!Type Point2(Type x, Type y)
70 		{
71 
72         	return Point2_(x,y);
73 		}
74     }
75 
76 
77 	static D2D1_POINT_2F
78     Point2F(
79         FLOAT x = 0.0f,
80         FLOAT y = 0.0f
81         )
82     {
83 		return D2D1_POINT_2F(x, y);
84     }
85 
86 	static D2D1_POINT_2U 
87 	Point2U(
88         UINT32 x = 0,
89         UINT32 y = 0
90         )
91     {
92 		return D2D1_POINT_2U(x, y);
93     }
94 
95 	template Size(Type) 
96 	{
97 		static TypeTraits!Type.Size Size( Type width, Type height )
98 		{
99 			TypeTraits!Type.Size size = { width, height };
100 			return size;
101 		}
102 	}
103 
104 	static D2D1_SIZE_F SizeF( FLOAT width = 0.0f, FLOAT height = 0.0f )
105 	{
106 		return Size!FLOAT(width, height);
107 	}
108 
109 	static D2D1_SIZE_U SizeU( UINT32 width = 0, UINT32 height = 0 )
110 	{
111 		return Size!UINT32(width, height);
112 	}
113 
114 
115     template Rect(Type)
116 	{
117 		static TypeTraits!Type.Rect Rect(
118         	Type left,
119         	Type top,
120         	Type right,
121         	Type bottom
122         	)
123     	{
124         	TypeTraits!Type.Rect rect = { left, top, right, bottom };
125         	return rect;
126     	}
127 	}
128 
129     static D2D1_RECT_F RectF(
130         FLOAT left = 0.0f,
131         FLOAT top = 0.0f,
132         FLOAT right = 0.0f,
133         FLOAT bottom = 0.0f
134         )
135     {
136         return Rect!FLOAT(left, top, right, bottom);
137     }
138 
139     static D2D1_RECT_U RectU(
140         UINT32 left = 0,
141         UINT32 top = 0,
142         UINT32 right = 0,
143         UINT32 bottom = 0
144         )
145     {
146         return Rect!UINT32(left, top, right, bottom);
147     }
148 
149     static D2D1_RECT_F
150     InfiniteRect()
151     {
152         D2D1_RECT_F rect = { -FloatMax(), -FloatMax(), FloatMax(),  FloatMax() };
153         return rect;
154     }
155 
156     static D2D1_ARC_SEGMENT
157     ArcSegment(
158         const(D2D1_POINT_2F) point,
159         const(D2D1_SIZE_F) size,
160         FLOAT rotationAngle,
161         const(D2D1_SWEEP_DIRECTION) sweepDirection,
162         const(D2D1_ARC_SIZE) arcSize
163         )
164     {
165         D2D1_ARC_SEGMENT arcSegment = { point, size, rotationAngle, sweepDirection, arcSize };
166 
167         return arcSegment;
168     }
169 
170     
171     static D2D1_BEZIER_SEGMENT
172     BezierSegment(
173         const(D2D1_POINT_2F) point1,
174         const(D2D1_POINT_2F) point2,
175 		const(D2D1_POINT_2F) point3
176         )
177     {
178         D2D1_BEZIER_SEGMENT bezierSegment = { point1, point2, point3 };
179 
180         return bezierSegment;
181     }
182 
183 	static D2D1_ELLIPSE
184     Ellipse(
185         in D2D1_POINT_2F center,
186         FLOAT radiusX,
187         FLOAT radiusY
188         )
189     {
190         D2D1_ELLIPSE ellipse;
191 
192         ellipse.point = center;
193         ellipse.radiusX = radiusX;
194         ellipse.radiusY = radiusY;
195 
196         return ellipse;
197     }
198 
199     static D2D1_ROUNDED_RECT
200     RoundedRect(
201         in D2D1_RECT_F rect,
202         FLOAT radiusX,
203         FLOAT radiusY
204         )
205     {
206         D2D1_ROUNDED_RECT roundedRect;
207 
208         roundedRect.rect = rect;
209         roundedRect.radiusX = radiusX;
210         roundedRect.radiusY = radiusY;
211 
212         return roundedRect;
213     }
214 
215     static D2D1_BRUSH_PROPERTIES
216     BrushProperties(
217         FLOAT opacity = 1.0,
218         in D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix()
219         )
220     {
221         D2D1_BRUSH_PROPERTIES brushProperties;
222 
223         brushProperties.opacity = opacity;
224         brushProperties.transform = transform;
225 
226         return brushProperties;
227     }
228 
229     static D2D1_GRADIENT_STOP
230     GradientStop(
231         FLOAT position,
232         in D2D1_COLOR_F color
233         )
234     {
235         D2D1_GRADIENT_STOP gradientStop = { position, color };
236 
237         return gradientStop;
238     }
239 
240     static D2D1_QUADRATIC_BEZIER_SEGMENT
241     QuadraticBezierSegment(
242         in D2D1_POINT_2F point1,
243         in D2D1_POINT_2F point2
244         )
245     {
246         D2D1_QUADRATIC_BEZIER_SEGMENT quadraticBezier = { point1, point2 };
247 
248         return quadraticBezier;
249     }
250 
251     static D2D1_STROKE_STYLE_PROPERTIES
252     StrokeStyleProperties(
253         D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT,
254         D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT,
255         D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT,
256         D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER,
257         FLOAT miterLimit = 10.0f,
258         D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID,
259         FLOAT dashOffset = 0.0f
260         )
261     {
262         D2D1_STROKE_STYLE_PROPERTIES strokeStyleProperties;
263 
264         strokeStyleProperties.startCap = startCap;
265         strokeStyleProperties.endCap = endCap;
266         strokeStyleProperties.dashCap = dashCap;
267         strokeStyleProperties.lineJoin = lineJoin;
268         strokeStyleProperties.miterLimit = miterLimit;
269         strokeStyleProperties.dashStyle = dashStyle;
270         strokeStyleProperties.dashOffset = dashOffset;
271 
272         return strokeStyleProperties;
273     }
274 
275     static D2D1_BITMAP_BRUSH_PROPERTIES
276     BitmapBrushProperties(
277         D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP,
278         D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP,
279         D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
280         )
281     {
282         D2D1_BITMAP_BRUSH_PROPERTIES bitmapBrushProperties;
283 
284         bitmapBrushProperties.extendModeX = extendModeX;
285         bitmapBrushProperties.extendModeY = extendModeY;
286         bitmapBrushProperties.interpolationMode = interpolationMode;
287 
288         return bitmapBrushProperties;
289     }
290 
291 	static D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES
292     LinearGradientBrushProperties(
293         in D2D1_POINT_2F startPoint,
294         in D2D1_POINT_2F endPoint
295         )
296     {
297         D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties;
298 
299         linearGradientBrushProperties.startPoint = startPoint;
300         linearGradientBrushProperties.endPoint = endPoint;
301 
302         return linearGradientBrushProperties;
303     }
304 
305 	static D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES
306     RadialGradientBrushProperties(
307         in D2D1_POINT_2F center,
308         in D2D1_POINT_2F gradientOriginOffset,
309         FLOAT radiusX,
310         FLOAT radiusY
311         )
312     {
313         D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties;
314 
315         radialGradientBrushProperties.center = center;
316         radialGradientBrushProperties.gradientOriginOffset = gradientOriginOffset;
317         radialGradientBrushProperties.radiusX = radiusX;
318         radialGradientBrushProperties.radiusY = radiusY;
319 
320         return radialGradientBrushProperties;
321     }
322 
323     //
324     // PixelFormat
325     // 
326 	static D2D1_PIXEL_FORMAT
327     PixelFormat(
328         in DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN,
329         in D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_UNKNOWN
330         )
331     {
332         D2D1_PIXEL_FORMAT pixelFormat;
333 
334         pixelFormat.format = dxgiFormat;
335         pixelFormat.alphaMode = alphaMode;
336 
337         return pixelFormat;
338     }
339 
340     //
341     // Bitmaps
342     // 
343 	static D2D1_BITMAP_PROPERTIES
344     BitmapProperties(
345         in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(),
346         FLOAT dpiX = 96.0f,
347         FLOAT dpiY = 96.0f
348         )
349     {
350         D2D1_BITMAP_PROPERTIES bitmapProperties;
351 
352         bitmapProperties.pixelFormat = pixelFormat;
353         bitmapProperties.dpiX = dpiX;
354         bitmapProperties.dpiY = dpiY;
355 
356         return bitmapProperties;
357     }
358 
359 
360     //
361     // Render Targets
362     // 
363     static D2D1_RENDER_TARGET_PROPERTIES
364     RenderTargetProperties(
365         D2D1_RENDER_TARGET_TYPE type =  D2D1_RENDER_TARGET_TYPE_DEFAULT,
366         in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(),
367         FLOAT dpiX = 0.0,
368         FLOAT dpiY = 0.0,
369         D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE,
370         D2D1_FEATURE_LEVEL  minLevel = D2D1_FEATURE_LEVEL_DEFAULT
371         )
372     {
373         D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties;
374 
375         renderTargetProperties.type = type;
376         renderTargetProperties.pixelFormat = pixelFormat;
377         renderTargetProperties.dpiX = dpiX;
378         renderTargetProperties.dpiY = dpiY;
379         renderTargetProperties.usage = usage;
380         renderTargetProperties.minLevel = minLevel;
381 
382         return renderTargetProperties;
383     }
384 
385 	static D2D1_RENDER_TARGET_PROPERTIES*
386 		RenderTargetPropertiesPtr(
387 			D2D1_RENDER_TARGET_TYPE type =  D2D1_RENDER_TARGET_TYPE_DEFAULT,
388 			in D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(),
389 			FLOAT dpiX = 0.0,
390 			FLOAT dpiY = 0.0,
391 			D2D1_RENDER_TARGET_USAGE usage = D2D1_RENDER_TARGET_USAGE_NONE,
392 			D2D1_FEATURE_LEVEL  minLevel = D2D1_FEATURE_LEVEL_DEFAULT
393 			)
394 	{
395 		D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties = new D2D1_RENDER_TARGET_PROPERTIES();
396 		
397 		renderTargetProperties.type = type;
398 		renderTargetProperties.pixelFormat = pixelFormat;
399 		renderTargetProperties.dpiX = dpiX;
400 		renderTargetProperties.dpiY = dpiY;
401 		renderTargetProperties.usage = usage;
402 		renderTargetProperties.minLevel = minLevel;
403 		
404 		return renderTargetProperties;
405 	}
406 	
407 	static D2D1_HWND_RENDER_TARGET_PROPERTIES
408 		HwndRenderTargetProperties(
409 			HWND hwnd,
410         in D2D1_SIZE_U pixelSize = D2D1.Size(cast(UINT32)0, cast(UINT32)0),
411         in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE
412         )
413     {
414         D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderTargetProperties;
415 
416         hwndRenderTargetProperties.hwnd = hwnd;
417         hwndRenderTargetProperties.pixelSize = pixelSize;
418         hwndRenderTargetProperties.presentOptions = presentOptions;
419 
420         return hwndRenderTargetProperties;
421     }
422 
423 	static D2D1_HWND_RENDER_TARGET_PROPERTIES*
424 		HwndRenderTargetPropertiesPtr(
425 			HWND hwnd,
426 			in D2D1_SIZE_U pixelSize = D2D1.Size(cast(UINT32)0, cast(UINT32)0),
427 			in D2D1_PRESENT_OPTIONS presentOptions = D2D1_PRESENT_OPTIONS_NONE
428 			)
429 	{
430 		D2D1_HWND_RENDER_TARGET_PROPERTIES* hwndRenderTargetProperties = new D2D1_HWND_RENDER_TARGET_PROPERTIES();
431 		
432 		hwndRenderTargetProperties.hwnd = hwnd;
433 		hwndRenderTargetProperties.pixelSize = pixelSize;
434 		hwndRenderTargetProperties.presentOptions = presentOptions;
435 		
436 		return hwndRenderTargetProperties;
437 	}
438 	
439 	static D2D1_LAYER_PARAMETERS
440 		LayerParameters(
441         in D2D1_RECT_F contentBounds = D2D1.InfiniteRect(),
442         ID2D1Geometry geometricMask = null,
443         D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
444         D2D1_MATRIX_3X2_F maskTransform = D2D1.IdentityMatrix(),
445         FLOAT opacity = 1.0,
446         ID2D1Brush opacityBrush = null,
447         D2D1_LAYER_OPTIONS layerOptions = D2D1_LAYER_OPTIONS_NONE
448         )
449     {
450         D2D1_LAYER_PARAMETERS layerParameters;
451 
452         layerParameters.contentBounds = contentBounds;
453         layerParameters.geometricMask = geometricMask;
454         layerParameters.maskAntialiasMode = maskAntialiasMode;
455         layerParameters.maskTransform = maskTransform;
456         layerParameters.opacity = opacity;
457         layerParameters.opacityBrush = opacityBrush;
458         layerParameters.layerOptions = layerOptions;
459 
460         return layerParameters;
461     }
462 
463     static D2D1_DRAWING_STATE_DESCRIPTION
464     DrawingStateDescription(
465         D2D1_ANTIALIAS_MODE antialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
466         D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
467         D2D1_TAG tag1 = 0,
468         D2D1_TAG tag2 = 0,
469         in D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix()
470         )
471     {
472         D2D1_DRAWING_STATE_DESCRIPTION drawingStateDescription;
473 
474         drawingStateDescription.antialiasMode = antialiasMode;
475         drawingStateDescription.textAntialiasMode = textAntialiasMode;
476         drawingStateDescription.tag1 = tag1;
477         drawingStateDescription.tag2 = tag2;
478         drawingStateDescription.transform = transform;
479 
480         return drawingStateDescription;
481     }
482 
483     //
484     // Colors, this enum defines a set of predefined colors.
485     //
486     struct ColorF
487     {
488     public:
489 		D2D1_COLOR_F color;
490 		alias color this;
491 
492 		alias Enum = uint;
493         enum : Enum
494         {
495             AliceBlue = 0xF0F8FF,
496             AntiqueWhite = 0xFAEBD7,
497             Aqua = 0x00FFFF,
498             Aquamarine = 0x7FFFD4,
499             Azure = 0xF0FFFF,
500             Beige = 0xF5F5DC,
501             Bisque = 0xFFE4C4,
502             Black = 0x000000,
503             BlanchedAlmond = 0xFFEBCD,
504             Blue = 0x0000FF,
505             BlueViolet = 0x8A2BE2,
506             Brown = 0xA52A2A,
507             BurlyWood = 0xDEB887,
508             CadetBlue = 0x5F9EA0,
509             Chartreuse = 0x7FFF00,
510             Chocolate = 0xD2691E,
511             Coral = 0xFF7F50,
512             CornflowerBlue = 0x6495ED,
513             Cornsilk = 0xFFF8DC,
514             Crimson = 0xDC143C,
515             Cyan = 0x00FFFF,
516             DarkBlue = 0x00008B,
517             DarkCyan = 0x008B8B,
518             DarkGoldenrod = 0xB8860B,
519             DarkGray = 0xA9A9A9,
520             DarkGreen = 0x006400,
521             DarkKhaki = 0xBDB76B,
522             DarkMagenta = 0x8B008B,
523             DarkOliveGreen = 0x556B2F,
524             DarkOrange = 0xFF8C00,
525             DarkOrchid = 0x9932CC,
526             DarkRed = 0x8B0000,
527             DarkSalmon = 0xE9967A,
528             DarkSeaGreen = 0x8FBC8F,
529             DarkSlateBlue = 0x483D8B,
530             DarkSlateGray = 0x2F4F4F,
531             DarkTurquoise = 0x00CED1,
532             DarkViolet = 0x9400D3,
533             DeepPink = 0xFF1493,
534             DeepSkyBlue = 0x00BFFF,
535             DimGray = 0x696969,
536             DodgerBlue = 0x1E90FF,
537             Firebrick = 0xB22222,
538             FloralWhite = 0xFFFAF0,
539             ForestGreen = 0x228B22,
540             Fuchsia = 0xFF00FF,
541             Gainsboro = 0xDCDCDC,
542             GhostWhite = 0xF8F8FF,
543             Gold = 0xFFD700,
544             Goldenrod = 0xDAA520,
545             Gray = 0x808080,
546             Green = 0x008000,
547             GreenYellow = 0xADFF2F,
548             Honeydew = 0xF0FFF0,
549             HotPink = 0xFF69B4,
550             IndianRed = 0xCD5C5C,
551             Indigo = 0x4B0082,
552             Ivory = 0xFFFFF0,
553             Khaki = 0xF0E68C,
554             Lavender = 0xE6E6FA,
555             LavenderBlush = 0xFFF0F5,
556             LawnGreen = 0x7CFC00,
557             LemonChiffon = 0xFFFACD,
558             LightBlue = 0xADD8E6,
559             LightCoral = 0xF08080,
560             LightCyan = 0xE0FFFF,
561             LightGoldenrodYellow = 0xFAFAD2,
562             LightGreen = 0x90EE90,
563             LightGray = 0xD3D3D3,
564             LightPink = 0xFFB6C1,
565             LightSalmon = 0xFFA07A,
566             LightSeaGreen = 0x20B2AA,
567             LightSkyBlue = 0x87CEFA,
568             LightSlateGray = 0x778899,
569             LightSteelBlue = 0xB0C4DE,
570             LightYellow = 0xFFFFE0,
571             Lime = 0x00FF00,
572             LimeGreen = 0x32CD32,
573             Linen = 0xFAF0E6,
574             Magenta = 0xFF00FF,
575             Maroon = 0x800000,
576             MediumAquamarine = 0x66CDAA,
577             MediumBlue = 0x0000CD,
578             MediumOrchid = 0xBA55D3,
579             MediumPurple = 0x9370DB,
580             MediumSeaGreen = 0x3CB371,
581             MediumSlateBlue = 0x7B68EE,
582             MediumSpringGreen = 0x00FA9A,
583             MediumTurquoise = 0x48D1CC,
584             MediumVioletRed = 0xC71585,
585             MidnightBlue = 0x191970,
586             MintCream = 0xF5FFFA,
587             MistyRose = 0xFFE4E1,
588             Moccasin = 0xFFE4B5,
589             NavajoWhite = 0xFFDEAD,
590             Navy = 0x000080,
591             OldLace = 0xFDF5E6,
592             Olive = 0x808000,
593             OliveDrab = 0x6B8E23,
594             Orange = 0xFFA500,
595             OrangeRed = 0xFF4500,
596             Orchid = 0xDA70D6,
597             PaleGoldenrod = 0xEEE8AA,
598             PaleGreen = 0x98FB98,
599             PaleTurquoise = 0xAFEEEE,
600             PaleVioletRed = 0xDB7093,
601             PapayaWhip = 0xFFEFD5,
602             PeachPuff = 0xFFDAB9,
603             Peru = 0xCD853F,
604             Pink = 0xFFC0CB,
605             Plum = 0xDDA0DD,
606             PowderBlue = 0xB0E0E6,
607             Purple = 0x800080,
608             Red = 0xFF0000,
609             RosyBrown = 0xBC8F8F,
610             RoyalBlue = 0x4169E1,
611             SaddleBrown = 0x8B4513,
612             Salmon = 0xFA8072,
613             SandyBrown = 0xF4A460,
614             SeaGreen = 0x2E8B57,
615             SeaShell = 0xFFF5EE,
616             Sienna = 0xA0522D,
617             Silver = 0xC0C0C0,
618             SkyBlue = 0x87CEEB,
619             SlateBlue = 0x6A5ACD,
620             SlateGray = 0x708090,
621             Snow = 0xFFFAFA,
622             SpringGreen = 0x00FF7F,
623             SteelBlue = 0x4682B4,
624             Tan = 0xD2B48C,
625             Teal = 0x008080,
626             Thistle = 0xD8BFD8,
627             Tomato = 0xFF6347,
628             Turquoise = 0x40E0D0,
629             Violet = 0xEE82EE,
630             Wheat = 0xF5DEB3,
631             White = 0xFFFFFF,
632             WhiteSmoke = 0xF5F5F5,
633             Yellow = 0xFFFF00,
634             YellowGreen = 0x9ACD32,
635         }
636         
637 
638         //
639         // Construct a color, note that the alpha value from the "rgb" component
640         // is never used.
641         // 
642         this(
643             UINT32 rgb,
644             FLOAT a = 1.0
645             )
646         {
647             Init(rgb, a);
648         }
649 		/*
650         this(
651             Enum knownColor,
652             FLOAT a = 1.0
653             )
654         {
655             Init(knownColor, a);
656         }
657         */
658 
659         this(
660             FLOAT r,
661             FLOAT g,
662             FLOAT b,
663             FLOAT a = 1.0
664             )
665         {
666             this.r = r;
667             this.g = g;
668             this.b = b;
669             this.a = a;
670         }
671 
672     private:
673 	
674         void
675         Init(
676             UINT32 rgb,
677             FLOAT a
678             )
679         {
680             this.r = cast(FLOAT)((rgb & sc_redMask) >> sc_redShift) / 255.0f;
681 			this.g = cast(FLOAT)((rgb & sc_greenMask) >> sc_greenShift) / 255.0f;
682 			this.b = cast(FLOAT)((rgb & sc_blueMask) >> sc_blueShift) / 255.0f;
683             this.a = a;
684         }
685 
686         static const UINT32 sc_redShift   = 16;
687         static const UINT32 sc_greenShift = 8;
688         static const UINT32 sc_blueShift  = 0;
689 
690         static const UINT32 sc_redMask = 0xff << sc_redShift;
691         static const UINT32 sc_greenMask = 0xff << sc_greenShift;
692         static const UINT32 sc_blueMask = 0xff << sc_blueShift;
693     }
694 
695 
696     struct Matrix3x2F //: public D2D1_MATRIX_3X2_F
697     {
698     public:
699 		D2D1_MATRIX_3X2_F matrix;
700 		alias matrix this;
701 
702 		this(D2D1_MATRIX_3X2_F m)
703 		{
704 			matrix = m;
705 		}
706 
707         this(
708             FLOAT _11,
709             FLOAT _12,
710             FLOAT _21,
711             FLOAT _22,
712             FLOAT _31,
713             FLOAT _32
714             )
715         {
716             this._11 = _11;
717             this._12 = _12;
718             this._21 = _21;
719             this._22 = _22;
720             this._31 = _31;
721             this._32 = _32;
722         }
723 
724         //
725         // Named quasi-constructors
726         //
727         static @property
728         Matrix3x2F
729         Identity()
730         {
731             Matrix3x2F identity;
732 
733             identity._11 = 1.0f;
734             identity._12 = 0.0f;
735             identity._21 = 0.0f;
736             identity._22 = 1.0f;
737             identity._31 = 0.0f;
738             identity._32 = 0.0f;
739 
740             return identity;
741         }
742 
743         static
744         Matrix3x2F
745         Translation(
746             D2D1_SIZE_F size
747             )
748         {
749             Matrix3x2F translation;
750 
751             translation._11 = 1.0; translation._12 = 0.0;
752             translation._21 = 0.0; translation._22 = 1.0;
753             translation._31 = size.width; translation._32 = size.height;
754 
755             return translation;
756         }
757 
758         static
759         Matrix3x2F
760         Translation(
761             FLOAT x,
762             FLOAT y
763             )
764         {
765             return Translation(SizeF(x, y));
766         }
767 
768 
769         static
770         Matrix3x2F
771         Scale(
772             D2D1_SIZE_F size,
773             D2D1_POINT_2F center = D2D1.Point2F()
774             )
775         {
776             Matrix3x2F scale;
777 
778             scale._11 = size.width; scale._12 = 0.0;
779             scale._21 = 0.0; scale._22 = size.height;
780             scale._31 = center.x - size.width * center.x;
781             scale._32 = center.y - size.height * center.y;
782 
783             return scale;
784         }
785 
786         static
787         Matrix3x2F
788         Scale(
789             FLOAT x,
790             FLOAT y,
791             D2D1_POINT_2F center = D2D1.Point2F()
792             )
793         {
794             return Scale(SizeF(x, y), center);
795         }
796 
797         static
798         Matrix3x2F
799         Rotation(
800             FLOAT angle,
801             D2D1_POINT_2F center = D2D1.Point2F()
802             )
803         {
804             Matrix3x2F rotation;
805 
806             D2D1MakeRotateMatrix(angle, center, &rotation.matrix);
807 
808             return rotation;
809         }
810 
811         static
812         Matrix3x2F
813         Skew(
814             FLOAT angleX,
815             FLOAT angleY,
816             D2D1_POINT_2F center = D2D1.Point2F()
817             )
818         {
819             Matrix3x2F skew;
820 
821             D2D1MakeSkewMatrix(angleX, angleY, center, &skew.matrix);
822 
823             return skew;
824         }
825 
826 		//TODO: find a way to do such manipulation
827 		/*
828         //
829         // Functions for convertion from the base D2D1_MATRIX_3X2_F to this type
830         // without making a copy
831         //
832         static
833         const(Matrix3x2F)*
834         ReinterpretBaseType(const(D2D1_MATRIX_3X2_F)* pMatrix)
835         {
836             return cast(const(Matrix3x2F)*)pMatrix;
837         }
838 
839         static
840         COM_DECLSPEC_NOTHROW
841         inline
842         Matrix3x2F*
843         ReinterpretBaseType(D2D1_MATRIX_3X2_F *pMatrix)
844         {
845             return static_cast<Matrix3x2F *>(pMatrix);
846         }
847         */
848 		 
849         FLOAT
850         Determinant() const
851         {
852             return (_11 * _22) - (_12 * _21);
853         }
854 
855         bool
856         IsInvertible() const
857         {
858             return !!D2D1IsMatrixInvertible(&this.matrix);
859         }
860 
861         bool
862         Invert()
863         {
864             return !!D2D1InvertMatrix(&this.matrix);
865         }
866 
867         bool
868         IsIdentity() const
869         {
870             return     _11 == 1.0f && _12 == 0.0f
871                     && _21 == 0.0f && _22 == 1.0f
872                     && _31 == 0.0f && _32 == 0.0f;
873         }
874 
875         void SetProduct(
876             in Matrix3x2F a,
877             in Matrix3x2F b
878             )
879         {
880             _11 = a._11 * b._11 + a._12 * b._21;
881             _12 = a._11 * b._12 + a._12 * b._22;
882             _21 = a._21 * b._11 + a._22 * b._21;
883             _22 = a._21 * b._12 + a._22 * b._22;
884             _31 = a._31 * b._11 + a._32 * b._21 + b._31;
885             _32 = a._31 * b._12 + a._32 * b._22 + b._32;
886         }
887 
888 		Matrix3x2F opBinary(string op)(Matrix3x2F rhs) const 
889 		{
890 			Matrix3x2F result;
891 
892 			static if (op == "*") 
893 				result.SetProduct(this,rhs);
894 			else 
895 				static assert(0, "Operator "~op~" not implemented");
896 
897 			return result;
898 		}
899 
900         D2D1_POINT_2F
901         TransformPoint(
902             D2D1_POINT_2F point
903             ) const
904         {
905             D2D1_POINT_2F result =
906             {
907                 point.x * _11 + point.y * _21 + _31,
908                 point.x * _12 + point.y * _22 + _32
909             };
910 
911             return result;
912         }
913 /* TODO
914 		static Matrix3x2F MakeFromBaseType(in D2D1_MATRIX_3X2_F mat)
915 		{
916 			Matrix3x2F matrix = new Matrix3x2F(mat);
917 			return matrix;
918 		}
919 		*/
920     }
921 
922     static IdentityMatrix()
923     {
924         return Matrix3x2F.Identity();
925     }
926 
927 } // namespace D2D1
928 
929 D2D1_POINT_2F opBinary(string op)(in D2D1_POINT_2F point, in D2D1_MATRIX_3X2_F matrix)
930 {
931 	return D2D1.Matrix3x2F.ReinterpretBaseType(&matrix).TransformPoint(point);
932 }
933 
934 /*
935 COM_DECLSPEC_NOTHROW
936 D2D1FORCEINLINE
937 D2D1_MATRIX_3X2_F
938 operator*(
939     const D2D1_MATRIX_3X2_F &matrix1,
940     const D2D1_MATRIX_3X2_F &matrix2
941     )
942 {
943     return
944         (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix1)) *
945         (*D2D1::Matrix3x2F::ReinterpretBaseType(&matrix2));
946 }
947 
948 COM_DECLSPEC_NOTHROW
949 inline
950 bool
951 operator==(const D2D1_SIZE_U &size1, const D2D1_SIZE_U &size2)
952 {
953     return (size1.width == size2.width) && (size1.height == size2.height);
954 }
955 
956 COM_DECLSPEC_NOTHROW
957 inline
958 bool
959 operator==(const D2D1_RECT_U &rect1, const D2D1_RECT_U &rect2)
960 {
961     return (rect1.left  == rect2.left)  && (rect1.top     == rect2.top) &&
962            (rect1.right == rect2.right) && (rect1.bottom  == rect2.bottom);
963 }
964 
965 #endif // #ifndef D2D_USE_C_DEFINITIONS
966 
967 #endif // #ifndef _D2D1_HELPER_H_
968 
969 */